package ylyhappy.cn.fileimport;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Settings;
import android.util.Log;
import android.widget.Button;

import androidx.activity.EdgeToEdge;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContract;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;

public class MainActivity extends AppCompatActivity implements
        RationalRequestAllFileAccessDialog.Listener, RationalRequestStorageAccessDialog.Listener {

    public interface Listener {
        void onShowRequestStorageAccessSuccess();
    }

    private Listener mListener;

    static private final String TAG = "APPPPP";
    private ActivityResultLauncher<Intent> filePickerLauncher;

    // ###################################### Permission Code ###############################################
    private final ActivityResultLauncher<String> requestStoragePermissionLauncher = registerForActivityResult(
            new ActivityResultContracts.RequestPermission(), e -> {
                this.onRequestStoragePermissionResult(e, mListener);
            }
    );

    private final ActivityResultLauncher<Listener> requestAllFilesAccessLauncher = registerForActivityResult(
            new RequestAllFilesAccessContract(), e -> {
                this.onRequestAllFilesAccessResult(e, mListener);
            }
    );


    private class RequestAllFilesAccessContract extends ActivityResultContract<Listener, Boolean> {
        @NonNull
        @Override
        @RequiresApi(Build.VERSION_CODES.R)
        public Intent createIntent(@NonNull Context context, Listener listener) {
            return new Intent(
                    Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION,
                    Uri.fromParts("package", context.getPackageName(), null)
            );
        }

        @Override
        @RequiresApi(Build.VERSION_CODES.R)
        public Boolean parseResult(int i, @Nullable Intent intent) {
            return Environment.isExternalStorageManager();
        }
    }

    /**
     * request permission callback
     * @param isGranted
     * @param mListener successfully callback
     */
    private void onRequestStoragePermissionResult(boolean isGranted, Listener mListener) {
        if (isGranted) {
            if (mListener != null) mListener.onShowRequestStorageAccessSuccess();
        } else if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            new RationalRequestStorageAccessDialog().show(getSupportFragmentManager(), "RationalRequestStorageAccessDialog");
        } else {
            new RationalRequestStorageAccessDialog().show(getSupportFragmentManager(), "RationalRequestStorageAccessDialog");
        }
    }

    private void onRequestStoragePermissionResult(boolean isGranted) {
        onRequestStoragePermissionResult(isGranted, null);
    }

    private void onRequestAllFilesAccessResult(boolean isGranted, Listener mListener) {
        Log.d(TAG, "onRequestStoragePermissionResult: Param is isGranted" + isGranted);
        if (isGranted) {
            if (mListener != null) mListener.onShowRequestStorageAccessSuccess();
        } else if (shouldShowRequestPermissionRationale(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)) {
            Log.d(TAG, "onRequestStoragePermissionResult: should show rational");
            new RationalRequestAllFileAccessDialog().show(getSupportFragmentManager(), "RationalRequestAllFileAccessDialog");
        } else {
            new RationalRequestAllFileAccessDialog().show(getSupportFragmentManager(), "RationalRequestAllFileAccessDialog");
        }
    }

    private void onRequestAllFilesAccessResult(boolean isGranted) {
        onRequestAllFilesAccessResult(isGranted, null);
    }

    private void requestAllFileAccessPermission() {
        requestAllFilesAccessLauncher.launch(null);
    }

    private void requestStorageAccessPermission() {
        requestStoragePermissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE);
    }

    @Override
    public void onShowRequestAllFilesAccessRationaleResult(boolean isYes) {
        if (isYes) {
            Log.d(TAG, "Requested all files access");
            requestAllFileAccessPermission();
        }
    }

    @Override
    public void onShowRequestStorageAccessRationaleResult(boolean isYes) {
        if (isYes) {
            Log.d(TAG, "Requested storage files access");
            requestStorageAccessPermission();
        }
    }

    /**
     * request permission
     * @param mListener request successfully callback
     */
    public void requestLocalStoragePermission(Listener mListener) {
        if (mListener != null){
            this.mListener = mListener;
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            if (!Environment.isExternalStorageManager()) {
                RationalRequestAllFileAccessDialog dialog = new RationalRequestAllFileAccessDialog();
                dialog.show(getSupportFragmentManager(), "rationalDialog");
            }
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // The current app does not have this permission. --> request
            Log.d(TAG, "Android SDK at 6 - 10");
            if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                Log.d(TAG, "Start Request Permission");
                // The current app should show rational dialog
                if (shouldShowRequestPermissionRationale(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)) {
                    Log.d(TAG, "Show Permission Rationale Dialog");
                    RationalRequestStorageAccessDialog dialog = new RationalRequestStorageAccessDialog();
                    dialog.show(getSupportFragmentManager(), "rationalDialog");
                } else {
                    this.onShowRequestStorageAccessRationaleResult(true);
                }
            }
        }
    }

    public void requestLocalStoragePermission() {
        requestLocalStoragePermission(null);
    }

    public boolean getLocalStoragePermissionStatus() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            return Environment.isExternalStorageManager();
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            return checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
        }
        return false; // no
    }
    // ###################################### Permission Code ###############################################

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setTitle("MainActivity");
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        // ###################################### Permission Code ###############################################
        Button request_btn = findViewById(R.id.request_permission);
        request_btn.setOnClickListener(e -> requestLocalStoragePermission());

        // ###################################### Permission Code ###############################################

        // ###################################### ContentProvider Code ##########################################
        Button import_btn = findViewById(R.id.import_file);
        import_btn.setOnClickListener(e -> {
            if (getLocalStoragePermissionStatus()){
                openFileManager();
            } else {
                requestLocalStoragePermission(() -> {
                    openFileManager();
                });
            }
        });
        filePickerLauncher = registerForActivityResult(
                new ActivityResultContracts.StartActivityForResult(),
                result -> {
                    if (result.getResultCode() == Activity.RESULT_OK) {
                        Intent data = result.getData();
                        if (data != null) {
                            Uri uri = data.getData();

                            String filePath = FileUtils.getRealPathFromURI_API19(this, uri);
                            Log.d(TAG, "filepath is: " + filePath);
                            // 处理选中的文件
                            try (BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(filePath))) {
                                byte[] buf = new byte[4096];
                                int rb;
                                while ((rb = bufferedInputStream.read(buf)) != -1) {
                                    String s = new String(buf, 0, rb, StandardCharsets.UTF_8);
                                    Log.d(TAG, "fileContent is: " + s);
                                }
                            } catch (FileNotFoundException e) {
                                throw new RuntimeException(e);
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                        }
                    }
                });
    }

    private void openFileManager() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("text/plain"); // 可以根据需要设置 MIME 类型
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        filePickerLauncher.launch(intent);
    }

    // ###################################### ContentProvider Code ##########################################

}